from goods.models import SKU
from django.template import loader
from django.conf import settings
import os
from meiduo_mall.utils.meiduo_channels import get_channels
from celery_tasks.main import app


@app.task(name='generate_detail_html')
def generate_detail_html(sku_id):
    # 查询
    try:
        sku = SKU.objects.get(pk=sku_id)  # 如sku_id=16
    except:
        print('商品编号[%d]无效' % sku_id)
    else:
        # 获取当前sku对象的所有规格对应的选项
        sku_option = []  # 存储选项的编号，因为一个商品有多个选项，所以是列表
        for sku_ss in sku.skuspecification_set.order_by('spec_id'):  # 6,7
            sku_option.append(sku_ss.option_id)  # [6-16,7-21]

        # 查询SKU对应的SPU对象
        goods = sku.goods
        # 增加channel属性，用于为第一级分类添加url链接
        goods.channel = goods.category1.goodschannel_set.all()[0]

        # 查询当前SPU对应的所有SKU的规格选项与SKU编号的对应信息
        skus = goods.sku_set.order_by('id')
        option_sku_dict = {}  # 键是选项列表，值是sku_id
        for s in skus:  # 9-16号商品
            # 获取指定s库存商品的所有规格对应的选项
            sku_option_all = s.skuspecification_set.order_by('spec_id')
            sku_option_list = []
            for o in sku_option_all:
                sku_option_list.append(o.option_id)  # [6-13,7-20]
            # 将选项与库存商品映射
            option_sku_dict[tuple(sku_option_list)] = s.id
        '''
        {
            (13,20):9,
            (13,21):10,
            (14,21):11,
            ....
        }
        '''

        # 查询所有规格
        specs = goods.goodsspecification_set.order_by('id')  # 2个
        # 查询每个规格的所有选项
        for index, spec in enumerate(specs):  # 0----6颜色，1-----7版本
            # 查询当前规格的所有选项
            options = spec.specificationoption_set.order_by('id')
            # 遍历所有选项，添加sku_id属性，指向某个sku对象的编号
            for option in options:
                # 深拷贝当前sku的规格选项信息
                s_option = sku_option[:]  # [6-16,7-21]
                # 改写指定位置的规格选项，其它选项保存不变
                s_option[index] = option.id  # [6-13,7-21]
                # 在字典中根据规格信息查找sku编号
                option.sku_id = option_sku_dict.get(tuple(s_option))  # 将选项添加到规格对象上
                # 为规格对象添加选项列表属性
                spec.options = options

        # 渲染
        template = loader.get_template('detail.html')
        html_text = template.render({
            'categories': get_channels(),  # 菜单
            'sku': sku,
            'goods': goods,
            'specs': specs
        })

        # 写文件
        with open(os.path.join(settings.GENERATE_STATIC_DIR, 'goods/%d.html' % sku_id), 'w') as f:
            f.write(html_text)

        print('ok')
